////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2008 Michiel Helvensteijn                                    //
//                                                                            //
// This file is part of the Mist compiler.                                    //
//                                                                            //
// The Mist compiler is free software: you can redistribute it and/or modif   //
// it under the terms of the GNU General Public License as published by       //
// the Free Software Foundation, either version 3 of the License, or          //
// (at your option) any later version.                                        //
//                                                                            //
// The Mist compiler is distributed in the hope that it will be useful,       //
// but WITHOUT ANY WARRANTY; without even the implied warranty of             //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              //
// GNU General Public License for more details.                               //
//                                                                            //
// You should have received a copy of the GNU General Public License          //
// along with the Mist compiler.  If not, see <http://www.gnu.org/licenses/>. //
////////////////////////////////////////////////////////////////////////////////

#ifndef OPTIONS_HPP
#define OPTIONS_HPP

/******************************************************************************
 * Includes                                                                   *
 ******************************************************************************/

#include <ostream>
using std::ostream;

#include <istream>
using std::istream;

#include <string>
using std::string;

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include <boost/shared_ptr.hpp>
using boost::shared_ptr;

#include <boost/scoped_ptr.hpp>
using boost::scoped_ptr;

class Messages;

/******************************************************************************
 * Extra Types                                                                *
 ******************************************************************************/

enum OutputType {
	OutputEcho        = 0x01,
	OutputAST         = 0x02,
	OutputSymbolTable = 0x04,
	OutputCPP         = 0x08
};

/******************************************************************************
 * Options Class                                                              *
 ******************************************************************************/

class Options {
	public:
		
		Options();
		
		~Options();
		
		void parse(int argc, char* argv[], shared_ptr<Messages> messages);
		
		void report_help(ostream& out) const;
		
		bool          version_asked()   const;
		bool          help_asked()      const;
		istream&      input()           const;
		ostream&      output()          const;
		const string& input_file()      const;
		const string& output_file()     const;
		unsigned      output_type()     const;
		unsigned      output_tab_size() const;
		bool          report_messages() const;
	
	private: // functions
		
		void set_options();
	
	private: // variables
		
		scoped_ptr<po::options_description>             _options;
		scoped_ptr<po::options_description>             _visibleOptions;
		scoped_ptr<po::positional_options_description>  _positional;
		
		bool _parsed;
		
		bool     _versionAsked;
		bool     _helpAsked;
		istream* _input;
		ostream* _output;
		string   _inputFile;
		string   _outputFile;
		unsigned _outputType;
		unsigned _sourceTabSize;
		unsigned _outputTabSize;
		bool     _reportMessages;
};

#endif // OPTIONS_HPP
